package com.zcbl.toolkit.http.request;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.io.IOUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * @author he peng
 * @create 2018/4/2 13:49
 * @see
 */

@Getter
@Setter
public class ReadStreamRequestWrapper extends HttpServletRequestWrapper {

    private byte[] rawBytes;
    private WrappedServletInputStream wrappedInputStream;

    public ReadStreamRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.rawBytes = IOUtils.toByteArray(request.getInputStream());
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.rawBytes);
        this.wrappedInputStream = new WrappedServletInputStream(byteArrayInputStream);
        resetInputStream();
    }

    private void resetInputStream() {
        this.wrappedInputStream.setInputStream(new ByteArrayInputStream(this.rawBytes != null ? this.rawBytes : new byte[0]));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return this.wrappedInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.wrappedInputStream));
    }

    @Data
    @AllArgsConstructor
    private static class WrappedServletInputStream extends ServletInputStream {

        private InputStream inputStream;

        @Override
        public boolean isFinished() {
            return true;
        }

        @Override
        public boolean isReady() {
            return false;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }

        @Override
        public int read() throws IOException {
            return this.inputStream.read();
        }
    }
}
